package com.maluxinyu.easyretry.service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.aizuda.easy.retry.client.core.annotation.Retryable;
import com.aizuda.easy.retry.client.core.retryer.RetryType;
import com.maluxinyu.easyretry.customized.MultiParamIdempotentGenerate;
import com.maluxinyu.easyretry.customized.OrderIdempotentIdGenerate;
import com.maluxinyu.easyretry.customized.OrderCompleteCallback;
import com.maluxinyu.easyretry.customized.OrderRetryMethod;
import com.maluxinyu.easyretry.customized.SingleParamIdempotentGenerate;
import com.maluxinyu.easyretry.dao.FailOrderBaseMapper;
import com.maluxinyu.easyretry.po.FailOrderPo;
import com.maluxinyu.easyretry.vo.OrderVo;

import cn.hutool.db.sql.Order;
import cn.hutool.json.JSONUtil;

/**
 * easy-retry中的远程重试
 */
@Component
public class RemoteRetryService {

    /**
     * 定义一个最基本的远程重试方法
     */
    @Retryable(scene = "remoteRetry",retryStrategy = RetryType.ONLY_REMOTE)
    public void remoteRetry(){
        System.out.println("远程重试方法启动");
        double i = 1 / 0;
    }

    /**
     * 使用先本地再远程的策略同步上传重试请求
     * retryStrategy = LOCAL_REMOTE 代表本地重试3次后再执行远程上报
     * async = false 代表使用同步上传的方式
     * timeout = 1 代表超时时间为1
     * unit = MINUTES 代表超时时间的单位是分钟
     */
    @Retryable(scene = "remoteRetryWithSync",retryStrategy = RetryType.LOCAL_REMOTE,
                async = false, timeout = 1, unit = TimeUnit.MINUTES)
    public String remoteRetryWithLocalRemote(String requestId){
        double i = 1 / 0;
        return requestId;
    }

    /**
     * 使用自定义的幂等Id生成类 OrderIdempotentIdGenerate
     */
    @Retryable(scene = "remoteRetryWithIdempotentId",retryStrategy = RetryType.ONLY_REMOTE,
                idempotentId = OrderIdempotentIdGenerate.class)
    public boolean remoteRetryWithIdempotentId(OrderVo orderVo){
        double i = 1 / 0;
        return true;
    }

    /**
     * 使用自定义的幂等Id生成类 SingleParamIdempotentGenerate
     * 测试单参数场景下
     */
    @Retryable(scene="retryWithSingleParamIdempotentGenerate",retryStrategy = RetryType.ONLY_REMOTE,
                idempotentId = SingleParamIdempotentGenerate.class)
    public boolean retryWithSingleParamIdempotentGenerate(String uuid){
        throw new NullPointerException();
    }

    /**
     * 使用自定义的幂等Id生成类 MultiParamIdempotentGenerate
     * 测试多个参数场景下的解析
     */
    @Retryable(scene = "retryWithMulParamIdempotentGenerate",retryStrategy = RetryType.ONLY_REMOTE,
                idempotentId = MultiParamIdempotentGenerate.class)
    public boolean retryWithMulParamIdempotentGenerate(String uuid,Integer intVal,Double doubleVal,
                                                       Character character,OrderVo orderVo){
        throw new NullPointerException();
    }

    /**
     * 使用自定义的异常处理类 OrderRetryMethod
     */
    @Retryable(scene = "remoteRetryWithRetryMethod", retryStrategy = RetryType.ONLY_REMOTE,
                retryMethod = OrderRetryMethod.class)
    public boolean remoteRetryWithRetryMethod(OrderVo orderVo){
        throw new NullPointerException();
    }

    /**
     * 使用自定义的retryCompleteCallback类 OrderCompleteCallback
     */
    @Retryable(scene = "remoteRetryWithCompleteCallback",retryStrategy = RetryType.LOCAL_REMOTE,
                retryCompleteCallback = OrderCompleteCallback.class)
    public boolean remoteRetryWithCompleteCallback(OrderVo orderVo){
        Random random = new Random();
        // 生成一个随机数，范围为0到1之间
        double probability = random.nextDouble();
        // 判断随机数是否小于等于0.5，即50%的概率
        if (probability <= 0.5) {
            // 生成的结果在50%的概率下执行这里的逻辑
            throw new NullPointerException();
        }
        return true;
    }

    /**
     * 自定义BizNo
     */
    @Retryable(scene = "remoteRetryWithBizNo",retryStrategy = RetryType.ONLY_REMOTE,bizNo = "orderVo.orderId")
    public boolean remoteRetryWithBizNo(OrderVo orderVo){
        throw new NullPointerException();
    }

}
